package com.loto.insurance.framework.Air.PA;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import javax.xml.ws.spi.http.HttpExchange;

import org.apache.commons.httpclient.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.message.BasicNameValuePair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.loto.insurance.framework.Air.InsAir;
import com.loto.insurance.framework.Air.InsReturnMsg;
import com.loto.insurance.framework.Air.OrderItemInfo;
import com.loto.insurance.framework.Air.PICC.PICCInsAir;
import com.loto.insurance.framework.config.ConfigManagementAir;
import com.loto.insurance.framework.config.PAConfigAir;
import com.loto.utils.DateUtils;
import com.loto.utils.Https;

public class PAInsAir implements InsAir {
  static Logger logger = LogManager.getLogger(PICCInsAir.class);

  private String productCode;

  private PAConfigAir paConfigAir;

  public PAInsAir(String productCode) {
	this.productCode = productCode;
	this.paConfigAir = getPaConfigAir();
  }

  @Override
  public InsReturnMsg PolicyApproval(OrderItemInfo info) {
	InsReturnMsg message = new InsReturnMsg();

	String postDocument = "<?xml version='1.0' encoding='GBK'?>"
	    + "<abbsParamXml>" + "<Header>" + "<documentId>001</documentId>"
	    + "<profileRequest>01</profileRequest>"
	    + "<function>policyIssuing</function>" + "<from>11-24-0001</from>"
	    + "<to>11-11-1111</to>" + "</Header>" + "<Request>" + "<policyIssuing>"
	    + "<paramList>" + "<parameter>" + "<policyNo>##policyNo##</policyNo>"
	    + "<name>##name##</name>" + "<productNo>##productNo##</productNo>"
	    + "<agencyNo>##agencyNo##</agencyNo>" + "<idType>##idType##</idType>"
	    + "<idNo>##idNo##</idNo>" + "<birthDate>##birthDate##</birthDate>"
	    + "<gender>##gender##</gender>" + "<units>1</units>"
	    + "<effDate>##effDate##</effDate>"
	    + "<matuDate>##matuDate##</matuDate>"
	    + "<contractNo>##contractNo##</contractNo>"
	    + "<flightNo>##flightNo##</flightNo>" + "<sumIns>##sumIns##</sumIns>"
	    + "<benLevel >##benLevel##</benLevel >"
	    + "<destination >##destination##</destination>"
	    + "<businessID>##businessID##</businessID>"
	    + "<operatorNo >##operatorNo##</operatorNo>"
	    + "<billNo>##billNo##</billNo>" + "<isSendSMS>1</isSendSMS>"
	    + "<mobile>##mobile##</mobile>" + "</parameter>" + "</paramList>"
	    + "</policyIssuing>" + "</Request>" + "</abbsParamXml>";

	// if (info.OrderNo.Contains("PCSH"))
	// {
	// //替换 总单号，是平安业务给代理点和合作公司提供
	// postDocument = postDocument.replace("##policyNo##", "GP02000000498742");
	// //替换 产品代码，是开发部门完成产品定义后生成的产品代码，也是业务提供给代理点或合作公司
	// postDocument = postDocument.replace("##productNo##", "P0122A2");
	// }
	// else
	// {
	// 替换 总单号，是平安业务给代理点和合作公司提供
	postDocument = postDocument.replace("##policyNo##",
	    paConfigAir.getPolicyNo());
	// 替换 产品代码，是开发部门完成产品定义后生成的产品代码，也是业务提供给代理点或合作公司
	postDocument = postDocument.replace("##productNo##",
	    paConfigAir.getProductNo());
	// }
	// 替换 起始时间
	postDocument = postDocument.replace("##effDate##",
	    DateUtils.dateToString(info.getFromPeriod(), "yyyyMMdd"));
	// 替换 结束时间
	/* 110804 jerry 修正平安保险期间6天的bug */

	postDocument = postDocument.replace("##matuDate##", DateUtils.dateToString(
	    DateUtils.addDays(info.getFromPeriod(), paConfigAir.getCycle()),
	    "yyyyMMdd"));

	// 替换 用户，平安表示代理点或合作公司，需要业务帮代理点或合作公司申请
	postDocument = postDocument.replace("##agencyNo##",
	    paConfigAir.getAgencyNo());
	// 替换 投保人
	postDocument = postDocument.replace("##name##", info.getInsuredName());
	// 替换 证件类型
	postDocument = postDocument.replace("##idType##",
	    getCertificateType(info.getInsuredCredentialType()));
	// 替换 证件号码
	postDocument = postDocument.replace("##idNo##",
	    info.getInsuredCredentialNo());
	// 替换 出生年月
	postDocument = postDocument.replace("##birthDate##",
	    DateUtils.dateToString(info.getInsuredBirth(), "yyyyMMdd"));
	// 替换 性别
	postDocument = postDocument.replace("##gender##",
	    getGender(info.getInsuredGender()));
	// 替换 只限小额信贷
	postDocument = postDocument.replace("##contractNo##", "");
	// 替换 航班号
	postDocument = postDocument.replace("##flightNo##", info.getFlightNo());
	// 替换 ##sumIns## 境外险产品必须
	postDocument = postDocument.replace("##sumIns##", "");
	// 替换 ##benLevel## 境外险产品必须
	postDocument = postDocument.replace("##benLevel##", "");
	// 替换 ##destination## 境外险产品必须
	postDocument = postDocument.replace("##destination##", "");
	// 替换 ##businessID##
	postDocument = postDocument.replace("##businessID##",
	    info.getTransOrderNo());
	// 替换 ##operatorNo##
	postDocument = postDocument.replace("##operatorNo##", "001");
	// 替换 ##billNo##
	postDocument = postDocument.replace("##billNo##", "");

	postDocument = postDocument.replace("##mobile##", info.getInsuredTel());

	String responseXml = null;
	String fullFileName = "WEB-INF\\resources\\config\\EXV.pfx";// paConfigAir.getCertificatePath();
	String path = this.getClass().getResource("").getPath()
	    .replaceAll("%20", " ");
	String fileName = path.substring(0, path.indexOf("WEB-INF")) + fullFileName;

	try {
	  URL newUrl = new URL(paConfigAir.getPostUrl());
	  URI uri = new URI(newUrl.getProtocol(), newUrl.getHost(),
		  newUrl.getPath(), newUrl.getQuery(), null);
	  responseXml = doPost(paConfigAir.getPostUrl(), postDocument, "GBK",
		  fileName, paConfigAir.getCertificatePassword());
	} catch (Exception e) {
	  // TODO Auto-generated catch block
	  e.printStackTrace();
	}
	logger.info(responseXml);
	return message;
  }

  @Override
  public InsReturnMsg PolicyQuery(OrderItemInfo info) {
	// TODO Auto-generated method stub
	return null;
  }

  @Override
  public InsReturnMsg PolicyCancel(OrderItemInfo info) {
	// TODO Auto-generated method stub
	return null;
  }

  public PAConfigAir getPaConfigAir() {
	ConfigManagementAir config = new ConfigManagementAir(productCode);
	return config.getPAConfiguration();
  }

  public String getProductCode() {
	return productCode;
  }

  public void setProductCode(String productCode) {
	this.productCode = productCode;
  }

  private String getGender(String gender) {
	String strGender = "M";
	if (gender == "女") {
	  strGender = "F";
	}
	return strGender;
  }

  private String getCertificateType(String certificateType) {
	if (certificateType == "身份证") {
	  return "1";
	} else if (certificateType == "军人证") {
	  return "3";
	} else if (certificateType == "护照") {
	  return "2";
	} else if (certificateType == "台胞证") {
	  return "5";
	} else {
	  return "9";
	}
  }

  private String doPost(String url, String xmlString, String charset,
	  String keyPath, String password) throws KeyStoreException,
	  NoSuchAlgorithmException, CertificateException, IOException,
	  KeyManagementException, UnrecoverableKeyException, URISyntaxException {

	String responseString = null;

	SSLContext sslContext = null;
	try {
	  TrustManager[] tm = { new MyX509TrustManager(keyPath, password) };
	  sslContext = SSLContext.getInstance("SSL", "SunJSSE");
	  sslContext.init(null, tm, null);//new java.security.SecureRandom()
	} catch (Exception e) {
	  // TODO Auto-generated catch block
	  e.printStackTrace();
	}
	// 从上述SSLContext对象中得到SSLSocketFactory对象
	SSLSocketFactory ssf = sslContext.getSocketFactory();
	// 创建URL对象
	/*
	 * List<BasicNameValuePair> params = new LinkedList<BasicNameValuePair>();
	 * params.add(new BasicNameValuePair("content", xmlString)); String
	 * requestParam = URLEncodedUtils.format(params, charset);
	 */
	HttpsURLConnection httpsConn = null;
	BufferedReader in = null;
	// DataOutputStream out = null;
	PrintWriter out = null;

	try {
	  URL myURL = new URL(url);
	  HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
	  // Create all-trusting host name verifier
	  HostnameVerifier allHostsValid = new HostnameVerifier() {
		@Override
		public boolean verify(String hostname, SSLSession session) {
		  return true;
		}
	  };
	  // Install the all-trusting host verifier
	  HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
	  /*
	   * end of the fix
	   */
	  // 创建HttpsURLConnection对象，并设置其SSLSocketFactory对象
	  httpsConn = (HttpsURLConnection) myURL.openConnection();
	  // httpsConn.setSSLSocketFactory(ssf);
	  httpsConn.setInstanceFollowRedirects(true);
	  httpsConn.setDoOutput(true);
	  httpsConn.setDoInput(true);
	  httpsConn.setRequestMethod("POST");
	  httpsConn.setRequestProperty("Content-Type", "text/xml");
	  httpsConn.setRequestProperty("charset", charset);
	  httpsConn.setRequestProperty("Connection", "Keep-Alive");
	  httpsConn
		  .setRequestProperty(
		      "Accept",
		      "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");
	  /*
	   * OutputStream outputStream = httpsConn.getOutputStream();
	   * outputStream.write(xmlString.getBytes(charset)); outputStream.flush();
	   * outputStream.close();
	   */
	  /*
	   * out = new DataOutputStream(httpsConn.getOutputStream()); if (xmlString
	   * != null) out.writeBytes(xmlString);
	   */
	  out = new PrintWriter(new OutputStreamWriter(httpsConn.getOutputStream(),
		  "GBK"));
	  // xmlString = xmlString.replaceAll("%", "%25");
	  out.print(xmlString);
	  out.print("\r\n");
	  out.flush();

	  // httpsConn.connect();
	  // 取得该连接的输入流，以读取响应内容
	  /*
	   * InputStreamReader insr = new
	   * InputStreamReader(httpsConn.getInputStream()); // 读取服务器的响应内容并显示 int
	   * respInt = insr.read(); while (respInt != -1) { System.out.print((char)
	   * respInt); respInt = insr.read(); logger.info(respInt); }
	   */

	  in = new BufferedReader(new InputStreamReader(httpsConn.getInputStream()));
	  int code = httpsConn.getResponseCode();
	  if (HttpsURLConnection.HTTP_OK == code) {
		String temp = in.readLine();
		/* 连接成一个字符串 */
		while (temp != null) {
		  if (responseString != null)
			responseString += temp;
		  else
			responseString = temp;
		  temp = in.readLine();
		}
	  }
	} catch (Exception e) {
	  e.printStackTrace();
	} finally {
	  out.flush();
	  out.close();
	  if (httpsConn != null) {
		httpsConn.disconnect();
	  }
	}
	return responseString;
  }
}
